import tools from '../../tools/tools'
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    showTodo: {
      type: Boolean,
      value: true
    },
    todos: {
      type: Array,
      value: []
    },
    minDate: {
      type: String,
      value: ''
    },
    tip: {
      type: Boolean,
      value: false
    }
  },
  externalClasses: [
    'calendar-class',
  ],
  /**
   * 组件的初始数据
   */
  data: {
    currentDate: new Date(),
    currentMonth: new Date().getMonth(),
    currentYear: new Date().getFullYear(),
    calendarDays: new Array(42).fill(null).map((_, index) => ({
      // 初始化一个具有稳定结构的数组
      date: '',
      day: '',
      isCurrentMonth: false,
      isToday: false,
      isSelected: false,
      isDisabled: true,
      hasTodo: false,
      hasHalfTodo: false,
      hasBothTodo: false,
    })),
    selectedDate: tools.formatDate(new Date()),
    weekDays: ['日', '一', '二', '三', '四', '五', '六'],
    isAddTodoDisabled: false,
    maxDate: tools.formatDate(new Date()),
  },
  /**
   * 监听属性变化
   */
  observers: {
    'todos': function (newTodos) {
      this.setData({
        isOpen: false
      })
      if(Array.isArray(newTodos) && newTodos.length) {
        const dateArr = newTodos[0].date.split('-')
        this.setData({
          currentMonth: dateArr[1] -1,
          currentYear: dateArr[0]
        })
      }
      this.generateCalendarDays(); // 数据变化时重新生成日历
    },
  },

  /**
   * 组件的方法列表
   */
  methods: {
    isOpen: true,
    // 日期格式化
    formatDate(date) {
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      return `${year}-${month}-${day}`;
    },

    // 解析日期字符串
    parseDate(dateStr) {
      if (!dateStr) return null;
      const [year, month, day] = dateStr.split('-').map(Number);
      return new Date(year, month - 1, day);
    },

    // 生成日历日期列表
    generateCalendarDays() {
      const { todos } = this.properties;
    const { currentYear, currentMonth, selectedDate, calendarDays } = this.data;

    // 获取当月第一天的星期
    const firstDayOfMonth = new Date(currentYear, currentMonth, 1).getDay();
    // 获取当月总天数
    const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
    
    // 创建一个临时数组来存放新数据，而不是直接修改 this.data.calendarDays
    const newCalendarDays = [...calendarDays];

    // --- 添加上月剩余天数 ---
    for (let i = 0; i < firstDayOfMonth; i++) {
      const dayInPrevMonth = new Date(currentYear, currentMonth, -i).getDate();
      const dateStr = this.formatDate(new Date(currentYear, currentMonth - 1, dayInPrevMonth));
      
      newCalendarDays[i] = {
        ...newCalendarDays[i], // 保留原有属性，防止丢失
        date: dateStr,
        day: dayInPrevMonth,
        isCurrentMonth: false,
        isToday: false,
        isSelected: dateStr === selectedDate,
        isDisabled: true,
        hasTodo: this.checkTodoExists(dateStr, todos),
        hasHalfTodo: this.checkHalfTodoExists(dateStr, todos),
        hasBothTodo: this.checkBothTodoExists(dateStr, todos),
      };
    }

    // --- 添加当月天数 ---
    for (let i = 0; i < daysInMonth; i++) {
      const dayInMonth = i + 1;
      const dateStr = this.formatDate(new Date(currentYear, currentMonth, dayInMonth));
      const currentDateObj = new Date(currentYear, currentMonth, dayInMonth);

      newCalendarDays[firstDayOfMonth + i] = {
        ...newCalendarDays[firstDayOfMonth + i],
        date: dateStr,
        day: dayInMonth,
        isCurrentMonth: true,
        isToday: this.isSameDay(currentDateObj, new Date()),
        isSelected: dateStr === selectedDate,
        isDisabled: this.isDateDisabled(currentDateObj),
        hasTodo: this.checkTodoExists(dateStr, todos),
        hasHalfTodo: this.checkHalfTodoExists(dateStr, todos),
        hasBothTodo: this.checkBothTodoExists(dateStr, todos),
      };
    }

    // --- 添加下月补充天数 ---
    const nextMonthStartIndex = firstDayOfMonth + daysInMonth;
    for (let i = 0; i < 42 - nextMonthStartIndex; i++) {
      const dayInNextMonth = i + 1;
      const dateStr = this.formatDate(new Date(currentYear, currentMonth + 1, dayInNextMonth));

      newCalendarDays[nextMonthStartIndex + i] = {
        ...newCalendarDays[nextMonthStartIndex + i],
        date: dateStr,
        day: dayInNextMonth,
        isCurrentMonth: false,
        isToday: false,
        isSelected: dateStr === selectedDate,
        isDisabled: true,
        hasTodo: this.checkTodoExists(dateStr, todos),
        hasHalfTodo: this.checkHalfTodoExists(dateStr, todos),
        hasBothTodo: this.checkBothTodoExists(dateStr, todos),
      };
    }
    
    this.setData({ calendarDays: newCalendarDays });
  },

    // 比较两个日期是否为同一天
    isSameDay(date1, date2) {
      return date1.getDate() === date2.getDate() &&
        date1.getMonth() === date2.getMonth() &&
        date1.getFullYear() === date2.getFullYear();
    },

    // 检查是否存在“全部打卡”
    checkTodoExists(date, todos) {
      return (todos || []).some(todo => todo.date === date && todo.type === 1);
    },

    // 检查是否存在“体重打卡，训练未打卡”
    checkHalfTodoExists(date, todos) {
      return (todos || []).some(todo => todo.date === date && todo.type === 2);
    },

    // 检查是否存在“体重未打卡，训练打卡”
    checkBothTodoExists(date, todos) {
      return (todos || []).some(todo => todo.date === date && todo.type === 3);
    },

    // 检查日期是否禁用
    isDateDisabled(date) {
      if (typeof date === 'string') {
        date = this.parseDate(date);
      }
      const { minDate, maxDate } = this.data;

      if (minDate && date < new Date(minDate)) return true;
      if (maxDate && date > new Date(maxDate)) return true;
      return false;
    },

    // 检查添加打卡是否禁用
    checkAddTodoDisabled() {
      const isDisabled = this.isDateDisabled(this.data.selectedDate);
      this.setData({ isAddTodoDisabled: isDisabled });
    },

    // 切换到上一月
    prevMonth() {
      let newMonth = this.data.currentMonth - 1;
      let newYear = this.data.currentYear;

      if (newMonth < 0) {
        newMonth = 11;
        newYear--;
      }
      // 1. 先执行“淡出”动画
      // this.fadeOutAnimation();
      const firstDayOfNewMonth = new Date(newYear, newMonth, 1);
      if (this.data.minDate && firstDayOfNewMonth < new Date(this.data.minDate)) {
        wx.showToast({ title: '已到达最小日期限制', icon: 'none' });
        return;
      }

      this.setData({ currentMonth: newMonth, currentYear: newYear }, () => {
        this.triggerEvent('monthChange', { year: newYear, month: newMonth + 1 });
      });
    },

    // 切换到下一月
    nextMonth() {
      let newMonth = this.data.currentMonth + 1;
      let newYear = this.data.currentYear;

      if (newMonth > 11) {
        newMonth = 0;
        newYear++;
      }
      // 1. 先执行“淡出”动画
      // this.fadeOutAnimation();
      const lastDayOfNewMonth = new Date(newYear, newMonth, 0);
      if (this.data.maxDate && lastDayOfNewMonth > new Date(this.data.maxDate)) {
        wx.showToast({ title: '已到达最大日期限制', icon: 'none' });
        return;
      }

      this.setData({ currentMonth: newMonth, currentYear: newYear }, () => {
        this.triggerEvent('monthChange', { year: newYear, month: newMonth + 1 });
      });
    },

    // 选择日期
    selectDate(e) {
      const { date, isdisabled } = e.currentTarget.dataset;
      if (isdisabled) return;
      const clickedDayItem = this.data.calendarDays.find(item => item.date === date);

      // 准备要传递给父组件的数据
      const eventDetail = {
        date: date,
        isdisabled: isdisabled,
        // 将打卡状态一同传递
        hasTodo: clickedDayItem?.hasTodo || false,
        hasBothTodo: clickedDayItem?.hasBothTodo || false,
        hasHalfTodo: clickedDayItem?.hasHalfTodo || false
      };
      this.setData({ selectedDate: date });
      this.generateCalendarDays();
      this.triggerEvent('dateChange', eventDetail);
    },

    // 触发添加打卡事件
    addTodo() {
      if (this.data.isAddTodoDisabled) return;
      this.triggerEvent('addTodo', { date: this.data.selectedDate });
    }
  }
})